#include "./../../../include/online/WebPageQuery/DataSql.h"
#include "./../../../include/online/Tools/Configuration.h"
#include "./../../../include/online/Tools/MyLogger.h"

#include <stdlib.h>
#include <unordered_map>
#include <string>
#include <iostream>

DataSql::DataSql() : _mysql(nullptr)
{
    unordered_map<string,string> configMap = Configuration::getInstance()->getConfigMap();

    _mysql = mysql_init(nullptr);
    if (!_mysql)
    {
        LogError("mysql_init failed");
        return;
    }

    MYSQL *ret = mysql_real_connect(_mysql,
                                    configMap["MYSQL_HOST"].c_str(),
                                    configMap["MYSQL_USER"].c_str(),
                                    configMap["MYSQL_PASSWD"].c_str(),
                                    configMap["MYSQL_DB"].c_str(),
                                    0, nullptr, 0);

    if (!ret)
    {
        LogError("mysql_real_connect failed: " + std::string(mysql_error(_mysql)));
        mysql_close(_mysql);
        _mysql = nullptr;
        return;
    }

    if (mysql_set_character_set(_mysql, "utf8") != 0)
    {
        LogError("mysql_set_character_set failed: " + std::string(mysql_error(_mysql)));
    }
}

DataSql::~DataSql()
{
    if (_mysql)
    {
        mysql_close(_mysql);
        _mysql = nullptr;
    }
}

void DataSql::query(const string &sql)
{
    if (!_mysql)
    {
        LogError("Query failed: MySQL not initialized");
        return;
    }

    int ret = mysql_query(_mysql, sql.c_str());
    if (ret != 0)
    {
        LogError("mysql_query failed: " + std::string(mysql_error(_mysql)));

        if (sql.size() > 100)
            LogInfo(sql.substr(0, 100).c_str());
        else
            LogInfo(sql.c_str());
    }
}

// 执行数据库修改操作（INSERT、UPDATE、DELETE）
void DataSql::update(const string &sql)
{
    if (!_mysql)
    {
        LogError("Update failed: MySQL not initialized");
        return;
    }

    int ret = mysql_query(_mysql, sql.c_str());
    if (ret != 0)
    {
        LogError("mysql_query (update) failed: " + std::string(mysql_error(_mysql)));

        if (sql.size() > 100)
            LogInfo(sql.substr(0, 100).c_str());
        else
            LogInfo(sql.c_str());

        return;
    }

    unsigned long long affectedRows = mysql_affected_rows(_mysql);
    LogInfo("Update successful, affected rows: " + std::to_string(affectedRows));
}

// 取出结果
MYSQL_RES *DataSql::store_result()
{
    if (!_mysql)
    {
        LogError("store_result failed: MySQL not initialized");
        return nullptr;
    }

    MYSQL_RES *res = mysql_store_result(_mysql);
    if (!res)
    {
        LogError("mysql_store_result failed: " + std::string(mysql_error(_mysql)));
    }
    return res;
}

// 是否有结果
unsigned long long DataSql::num_rows(MYSQL_RES *res)
{
    if (!res)
    {
        LogError("num_rows failed: NULL MYSQL_RES pointer");
        return 0;
    }
    return mysql_num_rows(res);
}

// 释放结果，调用此函数释放 MYSQL_RES 资源
void DataSql::free_result(MYSQL_RES *res)
{
    if (res)
        mysql_free_result(res);
}

// 取出一行
MYSQL_ROW DataSql::fetch_row(MYSQL_RES *res)
{
    if (!res)
    {
        LogError("fetch_row failed: NULL MYSQL_RES pointer");
        return nullptr;
    }
    return mysql_fetch_row(res);
}
